package com.daxue.common.http.core;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.StreamUtils;

import java.beans.ConstructorProperties;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
import java.util.Set;

/**
 * @author daxue0929
 * @date 2022/4/7
 */

public class RequestLoggingInterceptor implements ClientHttpRequestInterceptor {
    private static final Logger log = LoggerFactory.getLogger("com.yufu.idaas.extension.rest.base.core.RestClient");
    private static final String UNSET_RESOURCE_ID = "rc-799c847129c142e48dfc21bcb8-unset";
    private static final String UNSET_TENANT_ID = "tn-bd0a768f676d495ca462c15124-unset";
    private static final String ALL_RESOURCE_ID = "rc-*";
    private final String clientName;
    private final Set<String> logging;

    public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, final ClientHttpRequestExecution execution) throws
        IOException {
        String resourceId = (String) Optional.ofNullable(MDC.get("RESOURCE_ID")).orElse("rc-799c847129c142e48dfc21bcb8-unset");
        String tenantId = (String)Optional.ofNullable(MDC.get("TENANT_ID")).orElse("tn-bd0a768f676d495ca462c15124-unset");

        try {
            this.logRequest(tenantId, resourceId, request, body);
            ClientHttpResponse response = execution.execute(request, body);
            this.logResponse(tenantId, resourceId, request.getURI(), response);
            return response;
        } catch (IOException var7) {
            this.logException(tenantId, resourceId, request, var7);
            throw var7;
        }
    }

    private void logRequest(final String tenantId, final String resourceId, final HttpRequest request, final byte[] body) {
        if (this.logging.contains("rc-*") || this.logging.contains(resourceId)) {
            //log.info(LogMarker.builder().setIndex(resourceId).setTenantId(tenantId).setEventType("HTTP_REQUEST").setObjectType("REST_CLIENT").setDebugMsg(this.clientName).setDebugData("URI", request.getURI()).setDebugData("Method", request.getMethod()).setDebugData("Headers", request.getHeaders()).setDebugData("RequestBody", new String(body, StandardCharsets.UTF_8)).asMarker(), "[HttpRequest] request for tenantId:{}, resourceId: {}, URI: {}", new Object[]{tenantId, resourceId, request.getURI()});
            log.info("错误了");
        }

    }

    private void logResponse(final String tenantId, final String resourceId, final URI uri, final ClientHttpResponse response) {
        if (this.logging.contains(resourceId)) {
            try {
                //log.info(LogMarker.builder().setIndex(resourceId).setTenantId(tenantId).setEventType("HTTP_RESPONSE").setObjectType("REST_CLIENT").setDebugMsg(this.clientName).setDebugData("URI", uri).setDebugData("StatusCode", response.getStatusCode()).setDebugData("Status text", response.getStatusText()).setDebugData("Headers", response.getHeaders()).setDebugData("ResponseBody", StreamUtils.copyToString(response.getBody(), StandardCharsets.UTF_8)).asMarker(), "[HttpResponse] response for tenantId: {}, resourceId: {}, URI: {}", new Object[]{tenantId, resourceId, uri});
                log.info("错误了");
            //} catch (IOException var6) {
            } catch (Exception var6) {
                log.error(String.format("[HttpResponse] failed to parse response for tenantId: %s, resourceId: %s, URI: %s", tenantId, resourceId, uri), var6);
            }
        }

    }

    private void logException(final String tenantId, final String resourceId, final HttpRequest request, final IOException ex) {
        if (this.logging.contains(resourceId)) {
            log.info("错误了");
            //log.info(LogMarker.builder().setIndex(resourceId).setTenantId(tenantId).setEventType("HTTP_REQUEST_ERROR").setObjectType("REST_CLIENT").setDebugMsg(this.clientName).setDebugData("URI", request.getURI()).setDebugData("Method", request.getMethod()).setDebugData("Headers", request.getHeaders()).asMarker(), String.format("[HttpRequest] IOException for tenantId: %s, resourceId: %s, URI: %s", tenantId, request, request.getURI()), ex);
        }

    }

    @ConstructorProperties({"clientName", "logging"})
    public RequestLoggingInterceptor(final String clientName, final Set<String> logging) {
        this.clientName = clientName;
        this.logging = logging;
    }

}
